package org.rich.charlesmurphy.core.analyze;

import java.util.HashMap;
import java.util.Map;

import org.ddevil.data.set.BeanDataSet;
import org.ddevil.data.set.DataSet;
import org.rich.charlesmurphy.model.Request;
import org.rich.charlesmurphy.model.RequestGroup;
import org.rich.charlesmurphy.model.ResourceType;

/**
 * Assumes requests are in perfect order and will group them that way.  Each {@link ResourceType#PAGE} resource will
 * be considered a new page, and every subsequent found request will be considered generated from the page, until
 * a new page resource is encountered.
 * <br/>
 * i.e.
 * <pre>
 * pageAlpha.htm
 * style1.css (assumed to be from pageAlpha)
 * style2.css (assumed to be from pageAlpha)
 * script.js  (assumed to be from pageAlpha)
 * ...
 * </pre>
 * <p> *
 * The reality is that the access logs are often written in batch, and out of order. So the above page my appear in the logs like:
 * </p>
 * <pre>
 * style1.css
 * style2.css
 * page.htm
 * script.js
 * ...
 * </pre>
 *<p>
 * Access logs written like this would not be correctly analyzed by this analyzer. *
 *
 * @author Rich
 */
public class NaiveAnalyzer extends AbstractAnalyzer {

	/**
	 * {@inheritDoc}
	 */
	public DataSet<RequestGroup> analyze(DataSet<Request> coreData) {
		DataSet<RequestGroup> grouped = new BeanDataSet<RequestGroup>();

		Map<String, RequestGroup> groupsByClient = new HashMap<String, RequestGroup>();

		for (int i = 0; i < coreData.size(); i++) {

			Request record = coreData.exportRecord(i);
			if (accept(record)) {
				String path = record.getPath();
				String remoteHost = record.getRemoteHost();
				getLog().trace("Processing request: [{}]", record);

				// old comment -> .htm URL with no /async/ - assumed to be page load
				// for now be simple

				if (record.getResourceType() == ResourceType.PAGE) {//path.matches(".*\\.htm$") && !path.matches(".*/async/.*")) {
					getLog().trace("Request: [{}], determined to be new page load.", path);
					RequestGroup group = new RequestGroup(record);
					grouped.importRecord(group);
					groupsByClient.put(remoteHost, group);
				}
				else {

					RequestGroup group = groupsByClient.get(remoteHost);

					if (group != null) {
						getLog().trace("Adding: [{}], to the request group: [{}]", path, group.getPath());
						// integrate data into current group being worked
						group.addRequest(record);
					}
					else {
						getLog().debug("Request: [{}] does not associate with an existing group. Skipping.", record.toString());
					}
				}
			}
		}

		getLog().info("Done creating Grouped Request records.");
		return grouped;
	}
}
